package com.example.rtmppush;

import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.projection.MediaProjection;
import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

public class VideoCodec extends Thread{
    private String TAG ="VideoCodec";

    int width = 720;
    int height = 1080;
    MediaCodec mediaCodec;
    MediaProjection mediaProjection;

    ScreenLive screenLive;
    boolean isLive = true;
    String path ; // 写入本地文件

    private long startTime;//  编码开始时间

    VirtualDisplay virtualDisplay;
    public VideoCodec(MediaProjection mediaProjection, String path) {

        this.path = path;
        this.mediaProjection = mediaProjection;
        initEncoder();
    }
    public VideoCodec(MediaProjection mediaProjection) {
        this.mediaProjection = mediaProjection;
        initEncoder();
    }
    public VideoCodec(MediaProjection mediaProjection, ScreenLive screenLive) {
        this.screenLive = screenLive;
        this.mediaProjection = mediaProjection;
        initEncoder();
    }

    public void setPath(String path) {
        this.path = path;
    }

    private void initEncoder() {

        try {
            mediaCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);

            MediaFormat videoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height);
            videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE,15);
            // 1帧 一个 I帧
            videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,1);
            videoFormat.setInteger(MediaFormat.KEY_BIT_RATE,width * height);
            videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
            mediaCodec.configure(videoFormat,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);
            Surface inputSurface = mediaCodec.createInputSurface();
            virtualDisplay = mediaProjection.createVirtualDisplay("daidai", width, height, 2, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, inputSurface, null, null);
            mediaCodec.start();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"不支持的编码");
        }
    }

    @Override
    public void run() {
        super.run();

        isLive = true;
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        while (isLive) {
            int outIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,1000);
            if (outIndex >=0) {
                if (startTime==0) {
                    // us- >ms  dsp芯片 按照当时编码的系统时间打出来的
                    startTime = bufferInfo.presentationTimeUs/1000;
                }
                ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(outIndex);
                byte[] buff = new byte[outputBuffer.remaining()];
                outputBuffer.get(buff);
                //TODO 发送 RTMPPacket数据 screenLive 的阻塞队列
                if (screenLive != null) {
                    RTMPPacket rtmpPacket = new RTMPPacket(buff,(bufferInfo.presentationTimeUs/1000 - startTime));
                    rtmpPacket.setType(RTMPPacket.PACKET_VIDEO_TYPE);
                    screenLive.addPacket(rtmpPacket);
                    if (!screenLive.isAlive()) {
                        Log.e("rtmp","线程死了");
                    }else {
                        Log.e("rtmp","线程活着");
                    }

                }
                // 保存文件 ->SD卡
                if (!TextUtils.isEmpty(this.path)) {
                    writeFile(buff);
                }
                mediaCodec.releaseOutputBuffer(outIndex,false);
            }
        }

        //编码结束
        release();
    }

    private void release() {
        isLive = false;
        mediaCodec.stop();
        mediaCodec.release();
        mediaCodec =null;
        if (virtualDisplay!=null) {
            virtualDisplay.release();
            virtualDisplay =null;
        }
        if (mediaProjection!=null) {
            mediaProjection.stop();
            mediaProjection = null;
        }
    }
    void writeFile(byte[] buff) {
//      String path =  Environment.getExternalStorageDirectory().getAbsolutePath() + "/ScreenPush";
        File file = new File(path);

        if (!file.exists()) {
            boolean mkdir = file.mkdirs();
            Log.e(TAG,"path 创建成分股"+mkdir);
        }else  {
            Log.e(TAG,"path 存在"+path);
        }

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(path+"//screen.h264",true);
            try {
                fileOutputStream.write(buff);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
